const api = (function () {

    const api = {};
    api.debug = false;

    let _xhrFields = {};
    // 处理请求前xhr，每次请求完毕后还原为 {}
    Object.defineProperty(api, "xhrFields", {
        enumerable: false,
        get() {
            return _xhrFields;
        },
        set() {
            _xhrFields = {};
            return _xhrFields;
        }
    })

    /** 
     * 获取请求参数
     */
    function requestParams(params = {}, method = AJAX_PARAMS_MATHOD_JSON, takeCommonQuery = true) {
        let query = Object.assign({}, params);

        if (takeCommonQuery) {
            Object.assign(query, config.API_HEADER);
        }

        // undefined项转为""
        for (let i in query) {
            if (query[i] == undefined) {
                query[i] = "";
            }
        }

        switch (method) {
            case AJAX_PARAMS_MATHOD_JSON:
                return query;
            case AJAX_PARAMS_MATHOD_FORMDATA:
                let fd = new FormData;
                for (let i in query) {
                    fd.append(i, query[i]);
                }
                return fd;
            case AJAX_PARAMS_MATHOD_STRINGIFY:
                let s = [];
                for (let i in query) {
                    s.push(i + "=" + query[i]);
                }
                return s.join("&");
        }
    }

    function post(url, data, options = {}) {
        return $.ajax({
            url: url,
            type: 'POST',
            data: requestParams(data, AJAX_PARAMS_MATHOD_FORMDATA, true),
            cache: false,
            processData: false,
            contentType: false,
            headers: options.headers,
            xhrFields: Object.assign(api.xhrFields, options.xhrFields)
        });
    }

    function get(url, data, options = {}) {
        return $.ajax({
            url: url,
            type: 'GET',
            data: requestParams(data, AJAX_PARAMS_MATHOD_STRINGIFY, true),
            cache: false,
            processData: false,
            contentType: false,
            headers: options.headers,
            xhrFields: Object.assign(api.xhrFields, options.xhrFields)
        });
    }

    function jsonp(url, data, options = {}) {
        return $.ajax({
            url: url,
            type: 'JSONP',
            data: Object.assign(requestParams(data, AJAX_PARAMS_MATHOD_STRINGIFY), options.headers),
            cache: false,
            processData: false,
            contentType: false,
            xhrFields: Object.assign(api.xhrFields, options.xhrFields)
        });
    }

    /** 
     * 执行请求
     * 依赖 $.ajax
     */
    api.request = function (url, data = {}, options = {}) {
        if (util.isEmpty(url)) {
            throw "未指定请求地址";
        }

        if (url.indexOf("http") !== 0) {
            url = config.API_HOST + "" + url;
        }

        options = Object.assign({
            method: "POST",
            loading: true,
            headers: true,
            done: function () {},
            fail: function () {}
        }, options);

        if (["boolean", "object"].includes(util.type(options.headers))) {
            if (options.headers === false) {
                options.headers = {};
            } else if (options.headers === true) {
                options.headers = requestParams();
            } else {
                options.headers = Object.assign(requestParams(), options.headers);
            }
        }

        if (api.debug) {
            console.log(options.method + " " + url.replace("https://", ""), data);
        }

        let loading = {
            hide: function (callback) {callback && callback()}
        };
        if (options.loading) {
            // loading = component.loading();
        }

        let request;
        if (options.method == AJAX_REQUEST_GET) {
            request = get(url, data, options);
        } else if (options.method == AJAX_REQUEST_JSONP) {
            request = jsonp(url, data, options);
        } else {
            request = post(url, data, options);
        }

        return request
            .done(function (result) {
                loading.hide(() => {
                    // 如果请求成功，但接口返回失败，提示错误
                    if (result.success !== true) {
                        options.fail && options.fail({
                            code: result.code,
                            message: result.message,
                            data: result.data,
                            response: request
                        });
                        return;
                    }
                    options.done && options.done(result, true);
                });
            })
            .fail(function (e) {
                loading.hide(() => {
                    // 如果是手动中断，不弹出提示
                    if (e.statusText == 'abort') {
                        return false;
                    }
                    options.fail && options.fail({
                        code: -1,
                        message: '服务器繁忙，请重试',
                        data: {},
                        response: e
                    });
                });
            });
    };

    /** 
     * 获取esb图片
     */
    api.esbImageUrl = function (url) {
        var imgName = url.split(".")[0];
        return config.API_HOST + "/esb/res/pic/" + Math.floor(+imgName / 10000) + "/" + Math.floor(+imgName / 100) + "/" + url;
    }

    /** 
     * 注册jssdk
     * 需要引入wx模块
     */
    api.jssdkRegister = function (options={org_id:""}, callback, fail) {
        api.request(config.API_HOST + config.JSSDK_URL, Object.assign({
            url: window.location.href,
        }, options), {
            done(result) {
                let access = result.data;
                wx.init(access, {}, function () {
                    callback && callback();
                });
            }, 
            fail(e) {
                fail && fail(e);
            }
        });
    }

    // = block:main

    return api;
})();